#ifndef BOARD_H
#define BOARD_H

#include <esp_log.h>
#include <http.h>
#include <mqtt.h>
#include <udp.h>
#include <web_socket.h>

#include <string>

#include "backlight.h"
#include "board_config.h"
#include "button.h"
#include "driver/adc.h"
#include "driver/gpio.h"
#include "led/led.h"

void* create_board();
class AudioCodec;
class Display;

typedef std::function<void(const std::string& event_name, const std::string& detail)> BoardEventCallback;

class Board {
   private:
    Board(const Board&) = delete;             // 禁用拷贝构造函数
    Board& operator=(const Board&) = delete;  // 禁用赋值操作
    virtual std::string GetBoardJson() = 0;

   protected:
    Board();
    std::string GenerateUuid();

    // 软件生成的设备唯一标识
    std::string uuid_;
    BoardEventCallback event_callback_ = nullptr;  // board event

   public:
    enum class SinalStrength { ConfigAp, None, Weak, Good, Excellent };

    static Board& GetInstance() {
        static Board* instance = static_cast<Board*>(create_board());
        return *instance;
    }

    virtual ~Board() = default;
    virtual std::string GetBoardType() = 0;
    virtual std::string GetUuid() { return uuid_; }
    virtual Backlight* GetBacklight() { return nullptr; }
    virtual Led* GetLed();
    virtual AudioCodec* GetAudioCodec() = 0;
    virtual Display* GetDisplay();
    virtual Http* CreateHttp() = 0;
    virtual WebSocket* CreateWebSocket() = 0;
    virtual Mqtt* CreateMqtt() = 0;
    virtual Udp* CreateUdp() = 0;
    virtual void StartNetwork() = 0;
    virtual SinalStrength GetWiFiStrength() = 0;
    virtual std::string GetWiFiSSid() = 0;
    virtual std::string GetJson();
    virtual void SetPowerSaveMode(bool enabled) = 0;
    virtual bool GetButtonInfo(int& count, Button**& button) { return false; }
    virtual bool GetBatteryADCInfo(adc_channel_t& ch, float& ratio, gpio_num_t& chargingIO, bool& chargingIOState) { return false; }
    virtual bool GetBatteryLevel(int& level, bool& charging, bool& discharging);
    virtual void RegisterEventCallback(BoardEventCallback callback) { event_callback_ = callback; };
    virtual void ResetNetConfiguration() {};
    virtual bool NetIsConnected() { return false; };
    // 电池状态
    int bat_level_ = 0;
    bool bat_charging_ = false;
};

#define DECLARE_BOARD(BOARD_CLASS_NAME)                         \
    void* create_board() {                                      \
        ESP_LOGI("board", "board name: %s", #BOARD_CLASS_NAME); \
        return new BOARD_CLASS_NAME();                          \
    }

#endif  // BOARD_H
